package com.galaxy.service.service.system.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.galaxy.commom.base.exception.RequestException;
import com.galaxy.service.dto.system.resource.QueryPermissionDto;
import com.galaxy.service.entity.system.Permission;
import com.galaxy.service.mapper.system.PermissionMapper;
import com.galaxy.service.service.global.ShiroService;
import com.galaxy.service.service.system.PermissionService;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 权限接口实现类
 * @author caijinbang
 * @date 2018/10/27 19:14
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper,Permission> implements PermissionService {

    @Autowired
    private ShiroService shiroService;

  /**
   * 获取权限列表
   * @return
   */
  @Override
    public List<Permission> list() {
      EntityWrapper<Permission> wrapper = new EntityWrapper<>();
      wrapper.eq("parent_id",0).or().isNull("parent_id").orderBy("sort");
      List<Permission> resources = this.selectList(wrapper);
      if(resources!=null && resources.size()>0){
        resources.forEach(this::findAllChild);
      }
      return resources;
    }

  /**
   * 添加权限
   * @param queryPermissionDto
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
    public void add(QueryPermissionDto queryPermissionDto) {
      Permission permission = new Permission();
      BeanUtils.copyProperties(queryPermissionDto,permission);
      permission.setCreateDate(new Date());
      this.insert(permission);
      shiroService.reloadPerms();
    }

    @Override
    public void update(String id, QueryPermissionDto dto) {
      Permission resource = this.selectById(id);
      if(resource==null){
        throw RequestException.fail("更新失败，不存在ID为"+id+"的资源");
      }
      BeanUtils.copyProperties(dto,resource);
      this.updateById(resource);
      shiroService.reloadPerms();
    }

  /**
   * 移除权限
   * @param id
   */
  @Override
    public void remove(String id) {
      Permission resource = this.selectOne(new EntityWrapper<Permission>().eq("id",id).setSqlSelect("id"));
      if(resource==null){
        throw RequestException.fail("删除失败，不存在ID为"+id+"的资源");
      }
      this.deleteById(id);
      //移除后重新加载权限
      shiroService.reloadPerms();
    }

  /**
   * 查询子节点
   * @param resource
   */
  @Override
  public void findAllChild(Permission resource){
    EntityWrapper<Permission> wrapper = new EntityWrapper<>();
    wrapper.eq("parent_id",resource.getId()).orderBy("sort");
    List<Permission> resources = this.selectList(wrapper);
    resource.setChildren(resources);
    if(resources!=null && resources.size()>0){
      resources.forEach(this::findAllChild);
    }
  }

  /**
   * 获取所有父节点的权限
   * @param resource 资源
   * @param cacheMap 缓存对象
   * @param cacheMap2 缓存对象
   * @return
   */
  @Override
  public Permission getResourceAllParent(Permission resource,Map<String,Permission> cacheMap,
      Map<String,Permission> cacheMap2){
    if(resource.getParentId()!=null && !"".equals(resource.getParentId().trim())){
      Permission cacheParent = cacheMap.get(resource.getParentId());
      Permission parent;
      if(cacheParent!=null){
        parent = cacheParent;
      }else{
        cacheParent = cacheMap2.get(resource.getParentId());
        if(cacheParent!=null){
          parent = cacheParent;
        }else{
          parent = this.selectById(resource.getParentId());
        }
      }
      if(parent!=null){
        if(parent.getChildren()==null){
          parent.setChildren(new ArrayList<>());
        }
        //判断是否已经包含此对象
        if(!parent.getChildren().contains(resource)){
          parent.getChildren().add(resource);
        }
        cacheMap.put(resource.getParentId(),parent);
        //如果此父级还有父级，继续递归查询
        if(parent.getParentId()!=null && !"".equals(parent.getParentId())){
          return getResourceAllParent(parent,cacheMap,cacheMap2);
        }else{
          return parent;
        }
      }
    }
    return resource;
  }
}
